﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using OSCSchema;
using OutlookSocialProvider;

namespace OSC.Base
{
    internal class SocialPerson : ISocialPerson
    {
        #region Fields
        private readonly IPerson m_Person;
        private readonly ISocialConnector m_Session;
        private readonly ICachingStrategy m_CachingStrategy;
        private readonly IConverter<IPerson, personType> m_PersonConverter;
        private readonly IConverter<Activity, activityDetailsType> m_ActivityConverter;
        private readonly IConverter<IActivityTemplate, activityTemplateContainerType> m_ActivityTemplateConverter;
        private readonly IOSCSerializer m_Serializer;
        private byte[] m_Picture;
        #endregion

        #region Constructor
        public SocialPerson(IPerson person,
                            ISocialConnector session,
                            ICachingStrategy cachingStrategy,
                            IConverter<IPerson, personType> personConverter,
                            IConverter<Activity, activityDetailsType> activityConverter,
                            IConverter<IActivityTemplate, activityTemplateContainerType> activityTemplateConverter)
        {
            m_Person = person;
            m_Session = session;
            m_CachingStrategy = cachingStrategy;
            m_PersonConverter = personConverter;
            m_ActivityConverter = activityConverter;
            m_ActivityTemplateConverter = activityTemplateConverter;
            m_Serializer = new OSCSerializer();
        }
        #endregion

        #region Methods
        public string GetActivities(DateTime startTime)
        {
            var activities = GetActivities(m_Person.UserId, startTime);
            return GetActivityFeeds(activities);
        }
        protected IEnumerable<activityDetailsType> GetActivities(string userId, DateTime startTime)
        {
            return m_CachingStrategy.GetActivities(userId, startTime).Cast<Activity>().Select(m_ActivityConverter.Convert).ToArray();
        }
        protected string GetActivityFeeds(IEnumerable<activityDetailsType> activities)
        {
            var template = m_ActivityTemplateConverter.Convert(m_Session.GetActivityTemplate());
            var feed = new activityFeedType
            {
                activities = activities.ToArray(),
                network = m_Session.SiteUrl,
                templates = new[] { template }
            };
            return m_Serializer.Serialize(feed);
        }
        public string GetFriendsAndColleagues()
        {
            return m_Serializer.Serialize(new friends { person = m_CachingStrategy.GetFriends(m_Person.UserId).Select(m_PersonConverter.Convert).ToArray() });
        }
        public string[] GetFriendsAndColleaguesIDs()
        {
            return m_CachingStrategy.GetFriends(m_Person.UserId).Select(p => p.UserId).Distinct().ToArray();
        }
        public byte[] GetPicture()
        {
            return m_Picture ?? (m_Picture = GetUserProfilePicture());
        }
        public string GetStatus()
        {
            //Not supported in OSC version 1.0 and version 1.1
            throw new NotImplementedException();
        }
        public string GetDetails()
        {
            return m_Serializer.Serialize(m_PersonConverter.Convert(m_Person));
        }
        private byte[] GetUserProfilePicture()
        {
            if (m_Person.PictureUrl == null) return null;
            using (var client = new WebClient())
            {
                return client.DownloadData(m_Person.PictureUrl);
            }
        }
        #endregion
    }
}